Exercício 37#

Usar a STFT (quando possível) para analisar os sons de alguns sinais reais mencionados na Seção 5.3: a) fala; b) voz de cetáceo; c) som de hélice; d) resposta a irradiação por pulso de sonar; e) som de limpador de para-brisa; f) som de batida de porta; g) operação de máquina em funcionamento / em falha; h) operação de broca nova / gasta i) som de trompete; j) som de coração.

Resolução:#

O trabalho será realizado em python, em um notebook jupyter disponível a seguir, que pode ser acessado interativamente em https://www.smt.ufrj.br/~pedro.lopes/ex37/main.html. A STFT será realizada pela implementação da biblioteca librosa, junto com as funções para plotar os espectrogramas. Para facilitar a visualização, após a geração das STFT’s para cada sinal, mostraremos os respectivos espectrogramas de potência em escala logarítimica (dB).

Começamos por importar as bibliotecas necessárias:

import warnings
warnings.filterwarnings('ignore')
from librosa import stft 
import librosa.display
import soundfile as sf
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import Audio
plt.rcParams["figure.figsize"] = (14,8)
plt.plot()
plt.close()
plt.show()

Agora definimos as funções para ler os arquivos de áudio e fazer o plot dos espectrogramas. As STFT’s operam com tamanho de janela 2048 e salto de 512 amostras. Os outros parâmetros (formato da janela, padding, etc) são os padrões da biblioteca.

def get_spectrogram_data(signal,samplerate,n_fft=2048, hop_length=512,start=0,end=10):
    X = stft(signal[int(start*samplerate):int(end*samplerate)],n_fft=n_fft, hop_length=hop_length,win_length=n_fft)
    X_db = librosa.amplitude_to_db(np.abs(X), ref=np.max)
    return X_db

def play_audio(signal,samplerate,start=0,end=10):
    Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)

def plot_spectrogram(signal, samplerate,n_fft=2048, hop_length=512,start=0,end=10,y_axis='linear'):
    X_db = get_spectrogram_data(signal,samplerate,n_fft=n_fft, hop_length=hop_length,start=start,end=end)
    fig, ax = plt.subplots()
   
    img = librosa.display.specshow(X_db, sr=samplerate, x_axis='time', y_axis=y_axis, ax=ax)
    ax.set_title('Espectrograma de potência, escala log (dB)')
    fig.colorbar(img, ax=ax, format="%+2.0f dB")
    ax.set_xlabel("Tempo (s)")
    ax.set_ylabel("Frequência (Hz)")
    plt.show()

a) Começando pelo sinal de fala, temos:

signal,samplerate = sf.read('sinais/fala.wav')
s_8 = librosa.resample(signal,orig_sr=samplerate,target_sr=22050)
start = 0.4
end= 4.25
plot_spectrogram(s_8,22050,start=start,end=end,hop_length=512,n_fft=1024)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/2f141b817f1a6a5bc66a7c9a39969416ca72417983fd965390ba091d19251e21.png

b) Para os cetáceos, os sinais foram obtidos na página http://www-9.unipv.it/cibra/edu_medsounds_uk.html. Lá, podemos obter quatro classes de sons produzidos por estes tipos de animais:

  • Os sons de baixa frequência (por volta de 20 Hz);

  • Os cliques que as baleias cachalotes emitem com um ritmo de 1-4 por segundo enquanto mergulham;

  • Os assobios de alta frequência modulados (variando em frequência para mais de 20 kHz);

  • e os cliques de ecolocalização emitidos pelos golfinhos pequenos;

Para cada um deles, trazemos um exemplo.

Começando pelos sons de baixa frequência, mostramos estes em escala logarítimica de frequência (para melhor visualização) e acelerados em 8x (para possibilitar a audição):

signal,samplerate = sf.read('sinais/low_freq.wav')
start = 0.4
end= 4.25
plot_spectrogram(signal,samplerate,start=start,end=end,y_axis='log', hop_length=1024, n_fft=2048)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/fcb1f0a55c8be19bc55c450c99fff2a8babccc66a1246e50ea86df8773fc5d45.png

Agora os cliques das cachalotes:

signal,samplerate = sf.read('sinais/cachalotes_cliques.mp3')
signal = signal[:,0]
start = 3
end= 7
plot_spectrogram(signal,samplerate,start=start,end=end,hop_length=512,n_fft=1024)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/29e1d553f262408252493d07f6a15194f2f5aa88a64341b17e4e65a7f90660d5.png

Assobios agudos:

signal,samplerate = sf.read('sinais/assobios.wav')
start = 0.4
end= 6
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/eb83cd67c96df60029f5e8974fb51c5cc34b33d78d1116315592233d80829fe6.png
signal,samplerate = sf.read('sinais/ecolocalizacao.wav')
start = 0
end= 10
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/c2ea3135fdc496c92af2d84da49cfe662abd43a20131f3921eba4d1b4d71978f.png

Trazendo também o exemplo do livro, o som da “Bowhead Whale”:

signal,samplerate = sf.read('sinais/bowhead-whale.mp3')
signal = signal[:,0]
s_8 = librosa.resample(signal,orig_sr=samplerate,target_sr=8000)
start = 0
end= 10
plot_spectrogram(s_8,8000,start=start,end=end,hop_length=512,n_fft=1024)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/919b170363e24918c1a3a2f89d2ebda3844ab6d097d9baea6d354cde9172c6be.png

c) Para o som de hélice, trazemos o som de um motor de avião, encontrado no pixabay:

signal,samplerate = sf.read('sinais/helice.mp3')
signal = signal[:,0]
start = 0
end= 5
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/f5d50347edd81eb6d70cfd43c2578d6d3651f288e4f64815d2c984ce31e3ccaf.png

d) resposta a irradiação por pulso de sonar, retirada de https://www.youtube.com/watch?v=BIG7aQM83kI

signal,samplerate = sf.read('sinais/sonar.mp3')
signal = signal[:,0]
start = 19
end= 22
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/8e46e850efa2fe3a11801e87dc1497ab65b11186ad475c30d4fd1c821c9c3c1a.png

e) Para o som de limpador de parabrisa, também trazemos um exemplo encontrado no pixabay:

signal,samplerate = sf.read('sinais/para-brisas.mp3')
s_8 = librosa.resample(signal,orig_sr=samplerate,target_sr=16000)
start = 0
end= 4
plot_spectrogram(s_8,16000,start=start,end=end,hop_length=512,n_fft=1024)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/72949bb869ce6f977b767f39b7ca43b1197b01d2ab8bdd26ec37f52c089c2ee6.png

f) Também do pixabay, porta batendo:

signal,samplerate = sf.read('sinais/door-slam.mp3')
signal = signal[:,0]
start = 0
end= 5
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/a0b937b85abc1f76382ff7badf4c223767b808cc695046035091e57e55b5f9d2.png

h) operação de broca nova / gasta. Começando pela broca nova, obtida em https://www.youtube.com/watch?v=C0_M9rcWmY4:

signal,samplerate = sf.read('sinais/broca-nova.mp3')
signal = signal[:,0]
start = 14
end= 18
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/df4270c308f8187a2b2f89317193600a909720828f89a25219bd8913da59e63b.png

Broca gasta, obtida em https://youtu.be/0YflqwZgGls?si=8pGw1HwPp68w8G0e:

signal,samplerate = sf.read('sinais/broca-velha.mp3')
signal = signal[:,0]
start = 15
end= 17
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/6e20dd9bf40171a4b27fb37ee4bafb9e5d3df96f8c8f2c8109e9018b9775817f.png

i) som de trompete, obtido em https://freesfx.co.uk/sfx/trumpet:

signal,samplerate = sf.read('sinais/trumpet2.mp3')
signal = signal[:,0]
start = 0
end= 3
plot_spectrogram(signal,samplerate,start=start,end=end)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/60d65b2df8b22ce1d5ec4a5728bd4ee23172374c266dda6ea0afd7b33c6d3a9c.png

j) som de coração (pixabay)

signal,samplerate = sf.read('sinais/heart_beat.mp3')
signal = signal[:,0]
s_8 = librosa.resample(signal,orig_sr=samplerate,target_sr=4000)
start = 0
end= 4
plot_spectrogram(s_8,4000,start=start,end=end,hop_length=128,n_fft=256)
Audio(data=signal[int(start*samplerate):int(end*samplerate)], rate=samplerate)
_images/454cfffd674ff5176f21a0e6f31fda4b5dc6e67a7cc5e71657afac93fe6ea4b9.png